package soria.cabinet.security;

import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class RSA {
    private static final String ALGORITHM = "RSA";
    private static final int KEY_SIZE = 1024;

    protected static Map<String,String> generateKey(){
        KeyPairGenerator keyGenerator;
        try {
            keyGenerator = KeyPairGenerator.getInstance(ALGORITHM);
            SecureRandom random = new SecureRandom();
            random.setSeed(Device.getMAC());
            keyGenerator.initialize(KEY_SIZE, random);
            KeyPair keyPair = keyGenerator.genKeyPair();
            //获取公钥并转成base64编码
            byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
            //获取私钥并转成base64编码
            byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();

            String publicKey = Base64.getEncoder().encodeToString(publicKeyBytes);
            String privateKey = Base64.getEncoder().encodeToString(privateKeyBytes);
            Map<String,String> keyMap = new HashMap<>();
            keyMap.put("publicKey", publicKey);
            keyMap.put("privateKey", privateKey);
            return keyMap;
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * RSA公钥加密
     *
     * @param data 加密前的字符串
     * @param publicKey 公钥
     * @return 加密后的字符串
     */
    protected static String encrypt(String data, String publicKey) {
        try {
            //将公钥字符串转换为byte数组
            byte[] pubKey = Base64.getDecoder().decode(publicKey);
            //创建X509EncodedKeySpec对象，用于存储公钥
            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKey);
            //创建KeyFactory对象，指定加密算法
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
            //通过KeyFactory对象生成公钥
            PublicKey key = keyFactory.generatePublic(x509KeySpec);
            //创建Cipher对象，指定加密算法
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            //初始化Cipher对象，指定加密模式和公钥
            cipher.init(Cipher.ENCRYPT_MODE, key);
            //对数据加密
            byte[] encrypt = cipher.doFinal(data.getBytes());
            return Base64.getEncoder().encodeToString(encrypt);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * RSA私钥解密
     *
     * @param data 解密前的字符串
     * @param privateKey 私钥
     * @return 解密后的字符串
     */
    protected static String decrypt(String data, String privateKey) {
        try {
            //将base64编码的私钥解码
            byte[] priKey = Base64.getDecoder().decode(privateKey);
            //创建PKCS8编码的密钥规范
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey);
            //获取密钥工厂
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
            //根据密钥规范生成私钥
            PrivateKey key = keyFactory.generatePrivate(pkcs8KeySpec);
            //获取加密算法
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            //初始化加密模式
            cipher.init(Cipher.DECRYPT_MODE, key);
            //对数据解密
            return new String(cipher.doFinal(Base64.getDecoder().decode(data)));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
